using AutoMapper;
using MediatR;
using RBAC.Domain.MaterialManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.MaterialFile;
using System.Transactions;

namespace RBAC.Write.Api.Application.Handler.ERP.MaterialFile
{
    /// <summary>
    /// 更新物料基本档案处理类
    /// </summary>
    public class UpdateMaterialHandler : IRequestHandler<UpdateMaterialCommand, APIResult<bool>>
    {
        private readonly IBaseRepository<Mater> materRepository;
        private readonly IBaseRepository<MaterType> materTypeRepository;
        private readonly ILogger<UpdateMaterialHandler> logger;
        private readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="materRepository">物料仓储接口</param>
        /// <param name="materTypeRepository">物料类型仓储接口</param>
        /// <param name="logger">日志接口</param>
        /// <param name="mapper">对象映射接口</param>
        public UpdateMaterialHandler(
            IBaseRepository<Mater> materRepository,
            IBaseRepository<MaterType> materTypeRepository,
            ILogger<UpdateMaterialHandler> logger,
            IMapper mapper)
        {
            this.materRepository = materRepository;
            this.materTypeRepository = materTypeRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理更新物料请求
        /// </summary>
        /// <param name="request">更新物料请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新结果</returns>
        public async Task<APIResult<bool>> Handle(UpdateMaterialCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<bool>();

            try
            {
                logger.LogInformation("开始更新物料档案: {Id} - {MaterCode} - {MaterName}", 
                    request.Id, request.MaterCode, request.MaterName);

                // 1. 验证物料是否存在
                var existingMater = materRepository.QueryFirstOrDefault<Mater>(
                    "SELECT * FROM Mater WHERE Id = @Id AND IsDeleted = false",
                    new { Id = request.Id });

                if (existingMater == null)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料档案不存在";
                    logger.LogWarning("物料档案不存在: {Id}", request.Id);
                    return result;
                }

                // 2. 验证物料编码是否重复（排除当前记录）
                var duplicateCode = materRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM Mater WHERE MaterCode = @MaterCode AND Id != @Id AND IsDeleted = false",
                    new { request.MaterCode, request.Id });

                if (duplicateCode > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料编码已存在";
                    logger.LogWarning("物料编码重复: {MaterCode} (排除ID: {Id})", request.MaterCode, request.Id);
                    return result;
                }

                // 3. 验证物料名称是否重复（排除当前记录）
                var duplicateName = materRepository.QueryFirstOrDefault<int>(
                    "SELECT COUNT(1) FROM Mater WHERE MaterName = @MaterName AND Id != @Id AND IsDeleted = false",
                    new { request.MaterName, request.Id });

                if (duplicateName > 0)
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "物料名称已存在";
                    logger.LogWarning("物料名称重复: {MaterName} (排除ID: {Id})", request.MaterName, request.Id);
                    return result;
                }

                // 4. 验证物料分类是否存在（如果提供了分类ID）
                if (request.MaterTypeId.HasValue && request.MaterTypeId.Value > 0)
                {
                    var typeExists = materTypeRepository.QueryFirstOrDefault<int>(
                        "SELECT COUNT(1) FROM MaterType WHERE Id = @Id AND IsDeleted = false",
                        new { Id = request.MaterTypeId.Value });

                    if (typeExists == 0)
                    {
                        result.Code = APIEnums.Error;
                        result.Msg = "物料分类不存在";
                        logger.LogWarning("物料分类不存在: {MaterTypeId}", request.MaterTypeId.Value);
                        return result;
                    }
                }

                // 5. 执行更新操作
                using var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
                
                var updateSql = @"
                    UPDATE Mater SET
                        MaterCode = @MaterCode,
                        MaterName = @MaterName,
                        MaterTypeId = @MaterTypeId,
                        ModelSpec = @ModelSpec,
                        SpecDesc = @SpecDesc,
                        Unit = @Unit,
                        SupplyMode = @SupplyMode,
                        DrawingNo = @DrawingNo,
                        Status = @Status
                    WHERE Id = @Id";

                var affectedRows = materRepository.Execute(updateSql, new
                {
                    request.MaterCode,
                    request.MaterName,
                    request.MaterTypeId,
                    request.ModelSpec,
                    request.SpecDesc,
                    request.Unit,
                    request.SupplyMode,
                    request.DrawingNo,
                    request.Status,
                    request.Id
                });

                if (affectedRows > 0)
                {
                    scope.Complete();
                    result.Code = APIEnums.Success;
                    result.Msg = "更新成功";
                    result.Data = true;
                    logger.LogInformation("物料档案更新成功: {Id}", request.Id);
                }
                else
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "更新失败，未找到匹配的记录";
                    logger.LogWarning("物料档案更新失败，未找到匹配记录: {Id}", request.Id);
                }
            }
            catch (Exception ex)
            {
                result.Code = APIEnums.Error;
                result.Msg = "更新失败，请稍后重试";
                logger.LogError(ex, "更新物料档案异常: {Id}", request.Id);
            }

            return result;
        }
    }
}